

import SwiftUI

enum ProductType: String,CaseIterable {
    case iphone = "iPhone"
    case ipad = "iPad"
    case macbook = "MacBook"
    case desktop = "Mac Desktop"
    case appleWatch = "Apple Watch"
    case airpods = "Airpods"
    
    var tabID: String {
        /// Creating Another UniqueID for Tab Scrolling
        return self.rawValue + self.rawValue.prefix(4)
    }
}

struct Home: View {
    /// View Properties
    @State private var activeTab: ProductType = .iphone
    @Namespace private var animation
    @State private var animationProgress: CGFloat = 0
    /// Optional
    @State private var scrollableTabOffset: CGFloat = 0
    var body: some View {
        /// For Auto Scrolling Content's
        ScrollViewReader { proxy in
            ScrollView(.vertical, showsIndicators: false) {
                VStack(spacing: 15) {
                    ForEach(0..<20, id: \.self) { index in
                        Color.green.frame(height: 100)
                    }
                }
                .offset("CONTENTVIEW") { rect in
                    scrollableTabOffset = rect.minY
                    print("rect.minY = \(rect.minY)")
                }
            }
            .safeAreaInset(edge: .top) {
                ScrollableTabs(proxy)
                    .offset(y: scrollableTabOffset > 0 ? scrollableTabOffset : 0)
            }
            
        }
        .coordinateSpace(name: "CONTENTVIEW")
        .navigationTitle("Apple Store")
        .background {
            Rectangle()
                .fill(Color("BG"))
                .ignoresSafeArea()
        }
    }
    /// Scrollable Tabs
    @ViewBuilder
    func ScrollableTabs(_ proxy: ScrollViewProxy) -> some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 10) {
                ForEach(ProductType.allCases, id: \.rawValue) { type in
                    Text(type.rawValue)
                        .fontWeight(.semibold)
                        .foregroundColor(.white)
                        /// Active Tab Indicator
                        .background(alignment: .bottom, content: {
                            if activeTab == type {
                                Capsule()
                                    .fill(.white)
                                    .frame(height: 5)
                                    .padding(.horizontal, -5)
                                    .offset(y: 15)
                                    .matchedGeometryEffect(id: "ACTIVETAB", in: animation)
                            }
                        })
                        .padding(.horizontal, 15)
                        .contentShape(Rectangle())
                        /// Scrolling Tab's When ever the Active tab is Updated
                        .id(type.tabID)
                        .onTapGesture {
                            withAnimation(.easeInOut(duration: 0.3)) {
                                activeTab = type
                                animationProgress = 1.0
                                /// Scrolling To the Selected Content
                                proxy.scrollTo(type, anchor: .topLeading)
                            }
                        }
                }
            }
            .padding(.vertical, 15)
        }
        .background {
            Rectangle()
                .fill(Color("Purple"))
                .shadow(color: .black.opacity(0.2), radius: 5, x: 5, y: 5)
        }
    }
}

// MARK: - utilies

struct OffsetKey: PreferenceKey {
    static var defaultValue: CGRect = .zero
    
    static func reduce(value: inout CGRect, nextValue: () -> CGRect) {
        value = nextValue()
    }
}

extension View {
    @ViewBuilder
    func offset(_ coordinateSpace: AnyHashable, completion: @escaping (CGRect) -> ()) -> some View {
        self
            .overlay {
                GeometryReader {
                    let rect = $0.frame(in: .named(coordinateSpace))
                    
                    Color.clear
                        .preference(key: OffsetKey.self, value: rect)
                        .onPreferenceChange(OffsetKey.self, perform: completion)
                }
            }
    }
}


// MARK: - preview

struct Home_Previews: PreviewProvider {
    static var previews: some View {
        Home()
    }
}
